#pragma once

#include "map/terrain.h"

#include <unordered_map>

class TerrainManager : public cftf::util::Singleton<TerrainManager>
{
    friend class cftf::util::Singleton<TerrainManager>;
    TerrainManager();

    typedef std::unordered_map<unsigned int, TerrainInfo*> TerrainDataMap;

public:
    TerrainInfo* LoadTerrain(const unsigned int mapId);
    void UnloadTerrain(const unsigned int mapId);

    void Update(const unsigned int diff);
    void UnloadAll();

    unsigned short GetAreaFlag(unsigned int mapid, float x, float y, float z) const
    {
        TerrainInfo* pData = const_cast<TerrainManager*>(this)->LoadTerrain(mapid);
        return pData->GetAreaFlag(x, y, z);
    }
    unsigned int GetAreaId(unsigned int mapid, float x, float y, float z) const
    {
        return TerrainManager::GetAreaIdByAreaFlag(GetAreaFlag(mapid, x, y, z), mapid);
    }
    unsigned int GetZoneId(unsigned int mapid, float x, float y, float z) const
    {
        return TerrainManager::GetZoneIdByAreaFlag(GetAreaFlag(mapid, x, y, z), mapid);
    }
    void GetZoneAndAreaId(unsigned int& zoneid, unsigned int& areaid, unsigned int mapid, float x, float y, float z)
    {
        TerrainManager::GetZoneAndAreaIdByAreaFlag(zoneid, areaid, GetAreaFlag(mapid, x, y, z), mapid);
    }

    static unsigned int GetAreaIdByAreaFlag(unsigned short areaflag, unsigned int map_id);
    static unsigned int GetZoneIdByAreaFlag(unsigned short areaflag, unsigned int map_id);
    static void GetZoneAndAreaIdByAreaFlag(unsigned int& zoneid, unsigned int& areaid, unsigned short areaflag, unsigned int map_id);

private:
    ~TerrainManager();

    TerrainManager(const TerrainManager&);
    TerrainManager& operator=(const TerrainManager&);

#if 0
    typedef ACE_Thread_Mutex LOCK_TYPE;
    LOCK_TYPE m_mutex;
#endif
    TerrainDataMap i_TerrainMap;
};
